#include <asio.hpp>
#include <asio_adapting.h>

#include <google/protobuf/util/delimited_message_util.h>
#include <my_message.pb.h>

#include <iostream>

namespace Test_ReadProtobuf {
    void ReadProtobuf() {
        const char* hostname = "127.0.0.1";
        const char* port = "6000";
        asio::io_context ioc;
        asio::ip::tcp::resolver resolver(ioc);
        asio::ip::tcp::resolver::query query(hostname, port);
        asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
        asio::ip::tcp::socket socket(ioc);
        asio::connect(socket, endpoint_iterator);
        net::AsioInputStream<asio::ip::tcp::socket> ais(socket);
        google::protobuf::io::CopyingInputStreamAdaptor cis_adp(&ais);
        for(;;) {
            tutorial::searchRequest my_message;
            bool ec;
            google::protobuf::util::ParseDelimitedFromZeroCopyStream(&my_message, &cis_adp, &ec);
            std::cout << my_message.query() << std::endl;
        }
    }
};

#include <chat_message.pb.h>

using namespace std;
using asio::ip::tcp;


enum { max_length = 1024 };
int main(int argc, char* argv[]) {
    try {
        if (argc != 3)
        {
            std::cerr << "Usage: blocking_tcp_echo_client <host> <port>\n";
            return 1;
        }

        asio::io_context io_context;

        tcp::socket s(io_context);
        tcp::resolver resolver(io_context);
        asio::connect(s, resolver.resolve(argv[1], argv[2]));
        std::thread t([&]() { io_context.run(); });

        char request[max_length];
        while (std::cin.getline(request, max_length)) {
            chat::chat_message message;
            message.set_id(12);
            message.set_msg(request);
            auto bytes = message.SerializeAsString();
            size_t request_length = bytes.length();
            asio::write(s, asio::buffer(bytes, request_length));
            memset(request, 0, max_length);

            char reply[max_length];
            std::size_t reply_length = asio::read(s, asio::buffer(reply, request_length));
            reply[reply_length] = '\0';
            chat::chat_message reply_message;
            message.ParseFromString(reply);
            cout << "Reply: ";
            cout << message.msg() << endl;
        }
        t.join();
    }catch (std::exception& e) {
        cerr << "Exception: " << e.what() << endl;
    }

    return 0;
}